/**
 * Copyright (c) Daniel Centore
 *
 * ex: set filetype=java expandtab tabstop=4 shiftwidth=4 :
 *
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation.
 */
package ronp.anim.saving;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashSet;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import ronp.anim.data.filmstrip.Animation;

/**
 * Handles saving and loading {@link Animation}s
 * 
 * @author Daniel Centore
 *
 */
public class SaveHandler
{
	public static final String EXTENSION = "NPA"; // North Pole Animation
	public static final int FILETYPE_NPA = 0;
	public static final int FILETYPE_IMAGES = 1;

	/**
	 * Loads an {@link Animation} from a file
	 * @param file The {@link File} to load it from
	 * @return An {@link Animation} if it successfully loaded. Null otherwise.
	 */
	public static Animation loadAnimation(File file)
	{
		ObjectInputStream in = null;
		Animation anim = null;
		try
		{
			in = new ObjectInputStream(new FileInputStream(file));
			anim = (Animation) in.readObject();
			in.close();
		} catch (SecurityException e)
		{
			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		} catch (ClassNotFoundException e)
		{
			e.printStackTrace();
		} finally
		{
			try
			{
				in.close();
			} catch (IOException e)
			{
				e.printStackTrace();
			}
		}

		return anim;
	}

	/**
	 * Saves an {@link Animation} to a file
	 * @param anim The {@link Animation} to save
	 * @param file The {@link File} to save it to
	 */
	public static void saveAnimation(Animation anim, File file)
	{
		try
		{
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
			out.writeObject(anim);
			out.close();
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Creates a {@link JFileChooser} which uses NPA animation files
	 * @return The {@link JFileChooser}
	 */
	public static JFileChooser fileChooser(final int filetype)
	{
		JFileChooser chooser = new JFileChooser();
		FileFilter f;
		chooser.addChoosableFileFilter(f = new FileFilter()
		{
			@Override
			public String getDescription()
			{
				switch (filetype)
				{
				case FILETYPE_NPA:
					return "RONP Animation Files";

				case FILETYPE_IMAGES:
					return "Image Files (GIF, PNG, JPEG, ...)";

				default:
					throw new RuntimeException("Unrecognized filetype: [" + filetype + "]");
				}
			}

			@Override
			public boolean accept(File f)
			{
				if (!f.isFile()) // accept all directories
					return true;

				if (filetype == FILETYPE_NPA)
					return (f.getName().toLowerCase().endsWith("." + EXTENSION.toLowerCase()));
				else if (filetype == FILETYPE_IMAGES)
				{
					String[] formatNames = ImageIO.getReaderFormatNames();
					formatNames = unique(formatNames);

					for (String s : formatNames)
					{
						if (f.getName().toLowerCase().endsWith("." + s.toLowerCase()))
							return true;
					}

					return false;
				}
				else
					throw new RuntimeException("Unrecognized filetype: [" + filetype + "]");
			}
		});

		chooser.setFileFilter(f);

		return chooser;
	}

	// http://www.exampledepot.com/egs/javax.imageio/GetFormats.html
	public static String[] unique(String[] strings)
	{
		Set<String> set = new HashSet<String>();
		for (int i = 0; i < strings.length; i++)
		{
			String name = strings[i].toLowerCase();
			set.add(name);
		}
		return set.toArray(new String[0]);
	}

}
